home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / tek / sock / addsockport.c next >
C/C++ Source or Header  |  2001-05-12  |  5KB  |  195 lines

  1.  
  2. /* 
  3. **    TEKlib
  4. **    (C) 2001 TEK neoscientists
  5. **    all rights reserved.
  6. **
  7. **    TUINT portnr = TAddSockPort(TPORT *msgport, TUINT portnr, TTAGITEM *tags)
  8. **
  9. **    attach an invisible socket proxy to the given messageport,
  10. **    making it available via TCP/IP network.
  11. **
  12. **    msgport - msgport to add to the network.
  13. **    port    - port number to attach msgport to, or 0 for any port number
  14. **
  15. **    tags:
  16. **        TSock_IdleTimeout, TTIME *    
  17. **            timeout for idle connections. default: 100 seconds.
  18. **        TSock_MaxMsgSize, TUINT
  19. **            max msg size accepted from network, default: -1
  20. **
  21. **    TODO: add user msgmmu taglist argument
  22. **
  23. */
  24.  
  25. #include "tek/sock.h"
  26. #include "tek/debug.h"
  27. #include "tek/kn/exec.h"
  28. #include "tek/kn/sock.h"
  29.  
  30. struct socktaskinitdata
  31. {
  32.     TPORT *msgport;
  33.     TUINT portnr;                /* requested portnr, or 0 to allocate one */
  34.     TMMU *msgmmu;
  35.     TTIME idletimeout;
  36.     TUINT maxmsgsize;
  37. };
  38.  
  39. struct socktaskdata
  40. {
  41.     knsockobj sockname;            /* socket name object */
  42.     TBOOL destroysockname;
  43.     TUINT portnr;                /* actually assigned/allocated portnr */
  44.     TAPTR serversocket;            /* server socket object */
  45.     TPORT *msgport;                /* msgport added */
  46.     TPORT *replyport;            /* replyport proxied */
  47. };
  48.  
  49. static TBOOL socktaskinitfunc(TTASK *task);
  50. static TVOID socktaskfunc(TTASK *task);
  51.  
  52.  
  53. TUINT TAddSockPort(TPORT *msgport, TUINT portnr, TTAGITEM *tags)
  54. {
  55.     TUINT result = 0;
  56.     if (msgport)
  57.     {
  58.         kn_lock(&msgport->lock);
  59.         if (!msgport->proxy)
  60.         {
  61.             TTAGITEM tasktags[4];
  62.             struct socktaskinitdata initdata;
  63.             TTIME *idletime = (TTIME *) TGetTagValue(TSock_IdleTimeout, TNULL, tags);
  64.  
  65.             initdata.maxmsgsize = (TUINT) TGetTagValue(TSock_MaxMsgSize, (TTAG) 0xffffffff, tags);
  66.             initdata.msgport = msgport;
  67.             initdata.portnr = portnr;
  68.             initdata.msgmmu = ((TTASK *) msgport->sigtask)->msgmmu;
  69.  
  70.             if (idletime)
  71.             {
  72.                 initdata.idletimeout.sec = idletime->sec;
  73.                 initdata.idletimeout.usec = idletime->usec;
  74.             }
  75.             else
  76.             {
  77.                 initdata.idletimeout.sec = 128;
  78.                 initdata.idletimeout.usec = 0;
  79.             }
  80.             
  81.             tasktags[0].tag = TTask_InitFunc;
  82.             tasktags[0].value = (TTAG) socktaskinitfunc;
  83.             tasktags[1].tag = TTask_UserData;
  84.             tasktags[1].value = (TTAG) &initdata;
  85.             tasktags[2].tag = TTask_CreatePort;
  86.             tasktags[2].value = (TTAG) TFALSE;
  87.             tasktags[3].tag = TTAG_DONE;
  88.             
  89.             msgport->proxy = TCreateTask(msgport->sigtask, (TTASKFUNC) socktaskfunc, tasktags);
  90.             if (msgport->proxy)
  91.             {
  92.                 struct socktaskdata *data = TTaskGetData(msgport->proxy);
  93.                 result = data->portnr;
  94.             }
  95.         }
  96.         kn_unlock(&msgport->lock);
  97.     }
  98.     return result;
  99. }
  100.  
  101.  
  102.  
  103. static TBOOL socktaskinitfunc(TTASK *task)
  104. {
  105.     struct socktaskinitdata *initdata = TTaskGetData(task);
  106.     struct socktaskdata *data = TTaskAlloc(task, sizeof(struct socktaskdata));
  107.     if (data)
  108.     {
  109.         data->replyport = TCreatePort(task, TNULL);
  110.         if (data->replyport)
  111.         {
  112.             data->serversocket = TNULL;
  113.  
  114.             if (initdata->portnr)
  115.             {
  116.                 if ((data->destroysockname = kn_initsockname(&data->sockname, "0.0.0.0", initdata->portnr)))
  117.                 {
  118.                     data->portnr = initdata->portnr;
  119.                     data->serversocket = kn_createservsock(&task->heapmmu, initdata->msgmmu, &data->sockname, 
  120.                         initdata->maxmsgsize, &task->timer, &initdata->idletimeout, TNULL);
  121.                 }
  122.             }
  123.             else
  124.             {
  125.                 data->destroysockname = TFALSE;
  126.                 data->serversocket = kn_createservsock(&task->heapmmu, initdata->msgmmu, TNULL, 
  127.                     initdata->maxmsgsize, &task->timer, &initdata->idletimeout, &data->portnr);
  128.             }
  129.         
  130.             if (data->serversocket)
  131.             {
  132.                 data->msgport = initdata->msgport;
  133.                 task->userdata = data;
  134.                 return TTRUE;
  135.             }
  136.  
  137.             if (data->destroysockname)
  138.             {
  139.                 kn_destroysockname(&data->sockname);
  140.             }
  141.  
  142.             TDestroy(data->replyport);
  143.         }
  144.     }
  145.     return TFALSE;
  146. }
  147.  
  148.  
  149. /* 
  150. **    server task
  151. */
  152.  
  153. static TVOID socktaskfunc(TTASK *task)
  154. {
  155.     struct socktaskdata *data = task->userdata;
  156.     TMSG *msg;
  157.  
  158.     do
  159.     {
  160.         while ((msg = kn_getservsockmsg(data->serversocket)))
  161.         {
  162.             /* put msg to msgport */
  163.  
  164.             msg->replyport = data->replyport;
  165.             msg->status = TMSG_STATUS_SENT | TMSG_STATUS_PENDING;
  166.             kn_lock(&data->msgport->lock);
  167.             TAddTail(&data->msgport->msglist, (TNODE *) msg);
  168.             TSignal(data->msgport->sigtask, data->msgport->signal);
  169.             kn_unlock(&data->msgport->lock);
  170.         }
  171.  
  172.         kn_waitservsock(data->serversocket, &task->sigevent);
  173.  
  174.         while ((msg = (TMSG *) TGetMsg(data->replyport)))
  175.         {
  176.             kn_returnservsockmsg(data->serversocket, msg - 1);
  177.         }
  178.  
  179.     } while (!(TSetSignal(task, 0, data->replyport->signal) & TTASK_SIG_ABORT));
  180.  
  181.     kn_lock(&data->msgport->lock);
  182.     kn_destroyservsock(data->serversocket);
  183.     kn_unlock(&data->msgport->lock);
  184.  
  185.     if (data->destroysockname)
  186.     {
  187.         kn_destroysockname(&data->sockname);
  188.     }
  189.  
  190.     TDestroy(data->replyport);
  191.     
  192.     TTaskFree(task, data);            /* not really needed - task allocations will be freed on task exit */
  193. }
  194.  
  195.